package com.inspur.edp.bef.bemanager;


import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.inspur.edp.bef.bemanager.util.CheckInfoUtil;
import com.inspur.edp.bef.bizentity.GspBusinessEntity;
import com.inspur.edp.bef.bizentity.exceptions.BusinessEntityErrorCodeEnum;
import com.inspur.edp.bef.bizentity.exceptions.BusinessEntityException;
import com.inspur.edp.bef.bizentity.json.model.BizEntityDeserializer;
import com.inspur.edp.bef.bizentity.json.model.BizEntitySerializer;
import com.inspur.edp.cef.designtime.api.element.GspAssociation;
import com.inspur.edp.cef.designtime.api.element.GspElementObjectType;
import com.inspur.edp.das.commonmodel.IGspCommonElement;
import com.inspur.edp.das.commonmodel.IGspCommonModel;
import com.inspur.edp.lcm.metadata.api.IMetadataContent;
import com.inspur.edp.lcm.metadata.api.entity.GspMetadata;
import com.inspur.edp.lcm.metadata.api.service.RefCommonService;
import com.inspur.edp.lcm.metadata.spi.MetadataTransferSerializer;
import io.iec.edp.caf.commons.exception.ExceptionLevel;
import io.iec.edp.caf.commons.utils.SpringBeanUtils;

import java.util.ArrayList;

/**
 * Json序列化
 * 与前台交互
 */
public class TransferSerializer implements MetadataTransferSerializer {

    /**
     * json序列化
     *
     * @param metadataContent
     * @return
     */
    public final String serialize(IMetadataContent metadataContent) {

        GspBusinessEntity be = (GspBusinessEntity) ((metadataContent instanceof GspBusinessEntity) ? metadataContent : null);
        // 兼容关联子节点，RefObjectID,RefObjectCode,RefObjectName
        handleAssoRefObjectInfo(be);
        String eleJson;

        try {
            eleJson = getMapper().writeValueAsString(be);
        } catch (JsonProcessingException e) {
            throw BusinessEntityException.createException(BusinessEntityErrorCodeEnum.GSP_BEMODEL_JSON_0004, e, "GspBusinessEntity");
        }
        return eleJson;
    }


    private ObjectMapper getMapper() {
        ObjectMapper mapper = new ObjectMapper();
        SimpleModule module = new SimpleModule();
        module.addSerializer(IGspCommonModel.class, new BizEntitySerializer());
        module.addDeserializer(IGspCommonModel.class, new BizEntityDeserializer());
        mapper.registerModule(module);
        return mapper;
    }
    ///#region 关联子节点

    private void handleAssoRefObjectInfo(GspBusinessEntity be) {

        ArrayList<IGspCommonElement> elementList = be.getAllElementList(false);
        if (elementList.size() > 0) {

            for (IGspCommonElement ele : elementList) {
                handleAssoRefObjectInfo(ele);
            }
        }
    }

    private void handleAssoRefObjectInfo(IGspCommonElement element) {
        if (element.getObjectType() == GspElementObjectType.Association && element.getChildAssociations() != null && element.getChildAssociations().size() > 0) {

            for (GspAssociation asso : element.getChildAssociations()) {
                if (CheckInfoUtil.checkNull(asso.getRefObjectID())) {
                    RefCommonService metadataService = SpringBeanUtils.getBean(RefCommonService.class);

                    GspMetadata metadata = metadataService.getRefMetadata(asso.getRefModelID());

                    if (metadata.getContent() instanceof GspBusinessEntity) {
                        asso.setRefObjectID((((GspBusinessEntity) metadata.getContent()).getMainObject().getID()));
                        asso.setRefObjectCode(((GspBusinessEntity) metadata.getContent()).getMainObject().getCode());
                        asso.setRefObjectName(((GspBusinessEntity) metadata.getContent()).getMainObject().getName());
                    } else {
                        throw BusinessEntityException.createException(BusinessEntityErrorCodeEnum.GSP_BEMODEL_BUSINESS_ENTITY_0061,ExceptionLevel.Info, asso.getRefModelName(), asso.getRefModelID());
                    }
                }
            }
        }

    }

    ///#endregion

    /**
     * json反序列化
     *
     * @param contentString
     * @return
     */
    public final IMetadataContent deserialize(String contentString) {
        IMetadataContent content;
        try {
            content = (GspBusinessEntity) getMapper().readValue(contentString, GspBusinessEntity.class);
        } catch (JsonProcessingException e) {
            throw BusinessEntityException.createException(BusinessEntityErrorCodeEnum.GSP_BEMODEL_JSON_0001, e, "GspBusinessEntity");

        }
        return content;
    }
}